#include <string.h>
#include <stdlib.h>
#include <android/log.h>

#include "zbar.h"

#include "com_zbar_lib_ZbarManager.h"

JNIEXPORT jstring Java_com_zbar_lib_ZbarManager_decode(JNIEnv *env, jobject obj, jbyteArray img,
                                                       jint w,
                                                       jint h, jboolean isCrop, jint x, jint y,
                                                       jint cw, jint ch) {

    zbar_image_scanner_t *scanner;
    zbar_image_t *zimage;
    zbar_image_t *zgrayimage;

    jbyte *pixbuf;
    jstring s = NULL;//存储最终扫码结果
    __android_log_print(ANDROID_LOG_DEBUG, "zbar", "开始解析");
    //设置全局日志，值越高打印的日志越多
    zbar_set_verbosity(300); // XXX
    //将java数组转换为jbyte
    pixbuf = (*env)->GetByteArrayElements(env, img, 0);

    zimage = zbar_image_create();
    if (zimage == NULL) {
        __android_log_print(ANDROID_LOG_DEBUG, "zbar", "zbar_image_create fail");
        (*env)->ReleaseByteArrayElements(env, img, pixbuf, 0);
        return NULL;
    }

    zbar_image_set_format(zimage, *(unsigned long *) "Y800");

    zbar_image_set_size(zimage, w, h);

    zbar_image_set_data(zimage, pixbuf, (*env)->GetArrayLength(env, img),
                        zbar_image_free_data);

    if (isCrop) {
        zbar_image_set_crop(zimage, x, y, cw, ch);
    }

    zgrayimage = zbar_image_convert(zimage, *(unsigned long *) "Y800");

    if (zgrayimage == NULL) {
        __android_log_print(ANDROID_LOG_DEBUG, "zbar", "zbar_image_convert fail");
        (*env)->ReleaseByteArrayElements(env, img, pixbuf, 0);
        return NULL;
    }
    //销毁zimage
    zbar_image_destroy(zimage);

    scanner = zbar_image_scanner_create();
    int code = zbar_image_scanner_set_config(scanner, 0, ZBAR_CFG_ENABLE, 1);
    __android_log_print(ANDROID_LOG_DEBUG, "zbar", "zbar_image_scanner_set_config %d", code);
    //扫码识别关键代码
    int scanResCode = zbar_scan_image(scanner, zgrayimage);

    __android_log_print(ANDROID_LOG_DEBUG, "zbar", "zbar_scan_image %d", scanResCode);

    const zbar_symbol_t *sym;
    sym = zbar_image_first_symbol(zgrayimage);
    if (sym != NULL) {
        __android_log_print(ANDROID_LOG_DEBUG, "zbar", "zbar_image_first_symbol success");
        const char *sym_data;
        sym_data = zbar_symbol_get_data(sym);
        __android_log_print(ANDROID_LOG_DEBUG, "zbar", "url: %s", sym_data);
        s = (*env)->NewStringUTF(env, sym_data);
    } else {
        __android_log_print(ANDROID_LOG_DEBUG, "zbar", "zbar_image_first_symbol fail");
    }

    (*env)->ReleaseByteArrayElements(env, img, pixbuf, 0);
    return s;
}

